<!DOCTYPE html>
<html lang="en">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Porting to GCC 6</title>
<link rel="stylesheet" type="text/css" href="https://gcc.gnu.org/gcc.css" />
</head>

<body>
<h1>Porting to GCC 6</h1>

<p>
The GCC 6 release series differs from previous GCC releases in
<a href="changes.html">a number of ways</a>. Some of
these are a result of bug fixing, and some old behaviors have been
intentionally changed in order to support new standards, or relaxed
in standards-conforming ways to facilitate compilation or run-time
performance.  Some of these changes are not visible to the naked eye
and will not cause problems when updating from older versions.
</p>

<p>
However, some of these changes are visible, and can cause grief to
users porting to GCC 6. This document is an effort to identify major
issues and provide clear solutions in a quick and easily searched
manner. Additions and suggestions for improvement are welcome.
</p>


<h2 id="cxx">C++ language issues</h2>

<h3 id="gxx14">Default standard is now GNU++14</h3>

<p>
GCC 6 defaults to <code>-std=gnu++14</code> instead of <code>-std=gnu++98</code>:
the C++14 standard, plus GNU extensions.
This brings several changes that users should be aware of, some new with the C++14
standard, others that appeared with the C++11 standard.  The following
paragraphs describe some of these changes and suggest how to deal with them.
</p>

<p>Some users might prefer to stay with gnu++98, in which case we suggest to
use the <code>-std=gnu++98</code> command-line option, perhaps by putting it
in <code>CXXFLAGS</code> or similar variables in Makefiles.</p>

<p>Alternatively, you might prefer to update to gnu++11, bringing in the C++11
changes but not the C++14 ones.  If so, use the <code>-std=gnu++11</code>
command-line option.</p>

<h4 id="narrowing-conversions">Narrowing conversions</h4>

<p>
The C++11 standard does not allow "narrowing conversions" inside braced
initialization lists, meaning conversions to a type with less precision or
a smaller range, for example:
</p>
<pre><code>
    int i = 127;
    char s[] = { i, 256 };
</code></pre>

<p>
In the above example the value 127 would fit in <code>char</code> but
because it's not a constant it is still a narrowing conversion. If the value
256 is larger than <code>CHAR_MAX</code> then that is also a narrowing
conversion. Narrowing conversions can be avoided by using an explicit cast,
e.g. <code>(char)i</code>.
</p>

<h4 id="invalid-literal-suffixes">Invalid literal suffixes</h4>

<p>
The C++11 "user-defined literals" feature allows custom suffixes to be added
to literals, so that for example <code>"Hello, world!"s</code> creates a
<code>std::string</code> object. This means that code relying on string
concatenation of string literals and macros might fail to compile, for
example using <code>printf("%"PRIu64, uint64_value)</code> is not valid in
C++11, because <code>PRIu64</code> is parsed as a literal suffix. To fix
the code to compile in C++11 add whitespace between the string literal and the
macro: <code>printf("%" PRIu64, uint64_value)</code>.
</p>

<h4 id="null-pointer-constants">Cannot convert 'bool' to 'T*'</h4>

<p>
The current C++ standard only allows integer literals to be used as null
pointer constants, so other constants such as <code>false</code> and
<code>(1 - 1)</code> cannot be used where a null pointer is desired. Code that
fails to compile with this error should be changed to use <code>nullptr</code>,
or <code>0</code>, or <code>NULL</code>.
</p>

<h4 id="iostream-conversions">Cannot convert 'std::ostream' to 'bool'</h4>

<p>
As of C++11, iostream classes are no longer implicitly convertible to
<code>void*</code> so it is no longer valid to do something like:
</p>
<pre><code>
  bool valid(std::ostream&amp; os) { return os; }
</code></pre>

<p>
Such code must be changed to convert the iostream object to <code>bool</code>
explicitly, e.g. <code>return (bool)os;</code>
or
<code>return static_cast&lt;bool&gt;(os);</code>
</p>

<h4 id="iostream-comparisons">No match for 'operator!=' (operand types are 'std::ifstream' and 'int')</h4>

<p>
The change to iostream classes also affects code that tries to check for stream
errors by comparing to <code>NULL</code> or <code>0</code>.
Such code should be changed to simply test the stream directly, instead of
comparing it to a null pointer:
</p>

<pre><code>
  if (file) {   // not if (file != NULL), or if (file != 0)
    ...
  }
</code></pre>

<h4 id="complex-lvalues">Lvalue required as left operand of assignment with complex numbers</h4>

<p>
Since C++11 (as per DR#387) the member functions <code>real()</code> and 
<code>imag()</code> of <code>std::complex</code> can no longer be used as
lvalues, thus the following code is rejected:
</p>
<pre><code>
  std::complex&lt;double&gt; f;
  f.real () = val;
</code></pre>

<p>
To assign <code>val</code> to the real component of <code>f</code>, the
following should be used instead:
</p>
<pre><code>
  std::complex&lt;double&gt; f;
  f.real (val);
</code></pre>

<h4 id="dtors-default-to-noexcept">Destructors are <code>noexcept</code> by default</h4>

<p>
As of C++11, destructors have an implicit <code>noexcept</code>
exception-specification (unless a base class or non-static member variable has
a destructor that is <code>noexcept(false)</code>).  In practice this means that
the following program behaves differently in C++11 than in C++03:
</p>
<pre><code>
  #include &lt;stdexcept&gt;
  struct S
  {
    ~S() { throw std::runtime_error ("oops"); }
  };
  int
  main (void)
  {
    try { S s; }
    catch (...) {
      return 42;
    }
  }
</code></pre>

<p>
While in C++03 this program returns 42, in C++11 it terminates with a call to
<code>std::terminate</code>.  By default GCC will now issue a warning for
throw-expressions in <code>noexcept</code> functions, including destructors,
that would immediately result in a call to terminate.  The new warning can be
disabled with <code>-Wno-terminate</code>.  It is possible to restore the old
behavior when defining the destructor like this:
</p>
<pre><code>
    ~S() noexcept(false) { throw std::runtime_error ("oops"); }
</code></pre>

<h3 id="header-dep-changes">Header dependency changes</h3>

<p>
The <code>&lt;algorithm&gt;</code> header has been changed to reduce the
number of other headers it includes in C++11 mode or above.
As such, C++ programs that used components defined in
<code>&lt;random&gt;</code>, <code>&lt;vector&gt;</code>, or
<code>&lt;memory&gt;</code> without explicitly including the right headers
will no longer compile.
</p>

<h3 id="cmath">Header <code>&lt;cmath&gt;</code> changes</h3>

<p>
Some C libraries declare obsolete <code>int isinf(double)</code> or
<code>int isnan(double)</code> functions in the <code>&lt;math.h&gt;</code>
header. These functions conflict with standard C++ functions with the same
name but a different return type (the C++ functions return <code>bool</code>).
When the obsolete functions are declared by the C library the C++ library
will use them and import them into namespace <code>std</code>
instead of defining the correct signatures.
</p>

<h3 id="math.h">Header <code>&lt;math.h&gt;</code> changes</h3>

<p>
The C++ library now provides its own <code>&lt;math.h&gt;</code> header that
wraps the C library header of the same name. The C++ header defines
additional overloads of some functions and ensures that all standard
functions are defined as real functions and not as macros.
Code which assumes that <code>sin</code>, <code>cos</code>, <code>pow</code>,
<code>isfinite</code> etc. are macros may no longer compile.
</p>

<h3 id="stdlib.h">Header <code>&lt;stdlib.h&gt;</code> changes</h3>

<p>
The C++ library now provides its own <code>&lt;stdlib.h&gt;</code> header that
wraps the C library header of the same name. The C++ header defines
additional overloads of some functions and ensures that all standard
functions are defined as real functions and not as macros.
Code which assumes that <code>abs</code>, <code>malloc</code> etc.
are macros may no longer compile.
</p>

<p>
Programs which provide their own wrappers for <code>&lt;stdlib.h&gt;</code>
or other standard headers are operating outside the standard and so are
responsible for ensuring their headers work correctly with the headers in
the C++ standard library.
</p>

<h4 id="overloaded-abs">Call of overloaded '<code>abs(unsigned int&amp;)</code>' is ambiguous</h4>

<p>
The additional overloads can cause the compiler to reject invalid code that
was accepted before.  An example of such code is the below:
</p>

<pre><code>
#include &lt;stdlib.h&gt;
int
foo (unsigned x)
{
  return abs (x);
}
</code></pre>

<p>
Since calling <code>abs()</code> on an unsigned value doesn't make sense,
this code will become explicitly invalid as per discussion in the LWG.
</p>

<h3 id="this-cannot-be-null">Optimizations remove null pointer checks for <code>this</code></h3>

<p>
When optimizing, GCC now assumes the <code>this</code> pointer can never be
null, which is guaranteed by the language rules. Invalid programs which 
assume it is OK to invoke a member function through a null pointer (possibly
relying on checks like <code>this != NULL</code>) may crash or otherwise fail
at run time if null pointer checks are optimized away.
With the <code>-Wnull-dereference</code> option the compiler tries to warn
when it detects such invalid code.
</p>

<p>
If the program cannot be fixed to remove the undefined behavior then the
option <code>-fno-delete-null-pointer-checks</code> can be used to disable
this optimization. That option also disables other optimizations involving
pointers, not only those involving <code>this</code>.
</p>

<h3 id="deprecation-of-auto_ptr">Deprecation of <code>std::auto_ptr</code></h3>

<p>
The <code>std::auto_ptr</code> class template was deprecated in C++11, so GCC
now warns about its usage.  This warning can be suppressed with the
<code>-Wno-deprecated-declarations</code> command-line option, though we
advise to port the code to use C++11's <code>std::unique_ptr</code> instead.
</p>

<h3 id="constexpr-needed">'constexpr' needed for in-class initialization of static data member</h3>

<p>
Since C++11, the <code>constexpr</code> keyword is needed when initializing a
non-integral static data member in a class.  As a GNU extension, the following
program is accepted in C++03 (albeit with a <code>-Wpedantic</code> warning):
</p>

<pre><code>
struct X {
  const static double i = 10;
};
</code></pre>

<p>
The C++11 standard supports that in-class initialization using
<code>constexpr</code> instead, so the GNU extension is no longer supported for
C++11 or later.  Programs relying on the extension will be rejected with an
error.  The fix is to use <code>constexpr</code> instead of <code>const</code>.
</p>

<h3 id="flexible-array-members">Stricter flexible array member rules</h3>

<p>
As of this release, the C++ compiler is now more strict about flexible array
member rules.  As a consequence, the following code is no longer accepted:
</p>

<pre><code>
union U {
  int i;
  char a[];
};
</code></pre>

<p>
Furthermore, the C++ compiler now rejects structures with a flexible array
member as the only member:
</p>

<pre><code>
struct S {
  char a[];
};
</code></pre>

<p>
Finally, the type and mangling of flexible array members has changed
from previous releases.  While in GCC 5 and prior the type of a flexible
array member is an array of zero elements (a GCC extension), in GCC 6 it
is that of an array of an unspecified bound (i.e., <code>T[]</code> as opposed
to <code>T[0]</code>).  This is a silent ABI change with no corresponding
<code>-fabi-version</code> or <code>-Wabi</code> option to disable or warn
about.
</p>

<h3 id="flifetime-dse">More aggressive optimization of <code>-flifetime-dse</code></h3>

<p>
The C++ compiler (with <code>-flifetime-dse</code> enabled)
is more aggressive about dead-store elimination in situations where
a memory store to a location precedes the construction of an object at
that memory location. Such situations are commonly found in programs
which zero memory in a custom <code>new</code> operator:
</p>

<pre><code>
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;assert.h&gt;

struct A
{
 A() {}

 void* operator new(size_t s)
 {
   void* ptr = malloc(s);
   memset(ptr, 0xFF, s);
   return ptr;
 }

 void operator delete(void* ptr) { free(ptr); }

 int value;
};

int main()
{
 A* a =  new A;
 assert(a-&gt;value == -1); // Use of uninitialized value
 delete a;
}
</code></pre>

<p>
An object's constructor begins the lifetime of a new object at the relevant
memory location, so any stores to that memory location which happen before
the constructor are considered "dead stores" and so can be optimized away.
If the memory needs to be initialized to specific values then that should be
done by the constructor, not by code that happens before the constructor.
</p>

<p>
If the program cannot be fixed to remove the undefined behavior then
the option <code>-flifetime-dse=1</code> can be used to disable
this optimization.
</p>

<h2 id="Wmisleading-indentation">-Wmisleading-indentation</h2>
<p>
A new warning <code>-Wmisleading-indentation</code> was added
to <code>-Wall</code>, warning about places where the indentation of
the code might mislead a human reader about the control flow:
</p>

<blockquote><pre>
<b>sslKeyExchange.c:</b> In function <b>'SSLVerifySignedServerKeyExchange'</b>:
<b>sslKeyExchange.c:629:3:</b> <span class="boldmagenta">warning:</span> this <b>'if'</b> clause does not guard... [<span class="boldmagenta">-Wmisleading-indentation</span>]
    <span class="boldcyan">if</span> ((err = SSLHashSHA1.update(&amp;hashCtx, &amp;signedParams)) != 0)
    <span class="boldcyan">^~</span>
<b>sslKeyExchange.c:631:5:</b> <span class="boldcyan">note:</span> ...this statement, but the latter is misleadingly indented as if it is guarded by the <b>'if'</b>
        <span class="boldmagenta">goto</span> fail;
        <span class="boldmagenta">^~~~</span>
</pre></blockquote>

<p>
This has highlighted genuine bugs, often due to missing braces, but it
sometimes reports warnings for poorly-indented files, or on projects
with unusual indentation.  This may cause build errors if you
have <code>-Wall -Werror</code> in your project.
</p>

<p>
The best fix is usually to fix the indentation of the code to match
the block structure, or to fix the block structure by adding missing
braces.  If changing the source is not practical or desirable (e.g. for
autogenerated code, or to avoid churn in the source history), the
warning can be disabled by adding <code>-Wno-misleading-indentation</code>
to the build flags.  Alternatively, you can disable it for just one part of
a source file or function using pragmas:
</p>

<pre><code>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmisleading-indentation"

/* (code for which the warning is to be disabled)  */

#pragma GCC diagnostic pop
</code></pre>

<p>
Source files with mixed tabs and spaces that don't use 8-space tabs
may lead to warnings.  A real-world example was for such a source file, which
contained an Emacs directive to view tabs to be 4 spaces wide:
</p>

<blockquote><pre>
  /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
</pre></blockquote>

<p>
The mixture of tabs and spaces did correctly reflect the block
structure when viewed in Emacs, but not in other editors, or in an
HTML view of the source repository.
By default, <code>-Wmisleading-indentation</code> assumes tabs to
be 8 spaces wide.  It would have been possible to avoid this warning
by adding <code>-ftabstop=4</code> to the build flags for this file,
but given that the code was confusing when viewed in other editors,
the indentation of the source was fixed instead.
</p>

<h2 id="Wnonnull-compare">-Wnonnull-compare</h2>
<p>
A new warning <code>-Wnonnull-compare</code> was added to <code>-Wall</code>.
It warns about comparing parameters declared as <code>nonnull</code> with
<code>NULL</code>.  For example, the compiler will now warn about the following
code:
</p>

<pre><code>
__attribute__((nonnull)) void
foo (void *p)
{
  if (p == NULL)
    abort ();
  // ...
}
</code></pre>

<h2 id="plugins">Plugin issues</h2>

<p>
The internals of GCC have seen various improvements, and these may affect
plugins.  Some notes on porting GCC plugins to GCC 6 follow.
</p>

<h3 id="gimple-api"><code>gimple</code> became a struct, rather than a pointer</h3>

<p>
Prior to GCC 6, <code>gimple</code> meant a <b>pointer</b> to a statement.
It was a typedef aliasing the type <code>struct gimple_statement_base *</code>:
</p>

<pre><code>
/* Excerpt from GCC 5's coretypes.h.  */
typedef struct gimple_statement_base *gimple;
typedef const struct gimple_statement_base *const_gimple;
typedef gimple gimple_seq;
</code></pre>

<p>
As of GCC 6, the code above became:
</p>

<pre><code>
/* Excerpt from GCC 6's coretypes.h.  */
struct gimple;
typedef gimple *gimple_seq;
</code></pre>

<p><code>gimple</code> is now the statement <b>struct</b> itself, not
a pointer.  The <code>gimple</code> struct is now the base class of the
gimple statement class hierarchy, and throughout gcc every
instance of <code>gimple</code> was changed to a <code>gimple *</code>
(revision
<a href="https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=42acab1cd6812e2d9e49f4132176f5505f49a0e5">r227941</a>
is the commit in question).  The typedef <code>const_gimple</code> is no more;
use <code>const gimple *</code> if you need to represent a pointer
to a unmodifiable gimple statement.
</p>

<p>
Plugins that work with gimple will need to be updated to reflect this
change.  If you aim for compatibility between both GCC 6 and earlier
releases of GCC, it may be cleanest to introduce a compatibility typedef
in your plugin, such as:
</p>

<pre><code>
#if (GCC_VERSION >= 6000)
typedef gimple *gimple_stmt_ptr;
#else
typedef gimple gimple_stmt_ptr;
#end
</code></pre>

<h2 id="links">Links</h2>

<p>
Marek Polacek <a href="https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/message/DH7M2ADHM6XCRFTRRSKZD6MWFUJKHBZK/">Fedora mass rebuild 2016 on x86_64</a>
</p>

</body>
</html>
